home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / X11 / endo / rubber.c < prev    next >
C/C++ Source or Header  |  1995-05-12  |  15KB  |  560 lines

  1. /*************************************************************************
  2.  *                                                                       *
  3.  *  Copyright (c) 1992, 1993 Ronald Joe Record                           *
  4.  *                                                                       *
  5.  *  All rights reserved. No part of this program or publication may be   *
  6.  *  reproduced, transmitted, transcribed, stored in a retrieval system,  *
  7.  *  or translated into any language or computer language, in any form or *
  8.  *  by any means, electronic, mechanical, magnetic, optical, chemical,   *
  9.  *  biological, or otherwise, without the prior written permission of:   *
  10.  *                                                                       *
  11.  *      Ronald Joe Record (408) 458-3718                                 *
  12.  *      212 Owen St., Santa Cruz, California 95062 USA                   *
  13.  *                                                                       *
  14.  *************************************************************************/
  15.  
  16. #include <stdio.h>
  17. #include <values.h>
  18. #include "x.h"
  19. #ifdef USE_3D
  20. #include "globals.h"
  21. #endif
  22.  
  23. static int x_str, y_str;
  24. static int toggle=0, rubberband=0, winrot=0, segments=0;
  25. static char xystr[40];
  26. extern void Clear(), drawmap();
  27.  
  28. void
  29. drawhis()    /* using this color mapping, how many points are in each color ? */
  30. {
  31.     static int i, j, k, twid, minh, maxh;
  32.     static int h[MAXCOLOR];
  33.     static double d;
  34.     extern int minhist, maxhist, start;
  35.     extern int **histarray;
  36.  
  37.     XClearWindow(dpy, colwin);
  38.     for (i=0; i<MAXCOLOR; i++)
  39.         h[i] = 0;
  40.     minh = MAXINT; maxh = 0;
  41.     if (thermometer)
  42.         twid = trawidth - THERMWIDTH;
  43.     else
  44.         twid = trawidth;
  45.     for (i=0; i<traheight; i++)
  46.         for (j=0; j<twid; j++)
  47.             if ((histarray[j][i]) && (maxhist > minhist)) {
  48.                 d = (double)(histarray[j][i]-minhist)/(double)(maxhist-minhist);
  49.                 k = get_hist_index(d);
  50.                 h[k]++;
  51.                 if (h[k] > maxh) maxh = h[k];
  52.                 if (h[k] < minh) minh = h[k];
  53.             }
  54.     k = ADJWIDTH / MAXCOLOR;
  55.     for (i=0; i<ADJWIDTH; i+=k) {
  56.         j = ADJHEIGHT * (h[(i/k)] - minh) / (maxh - minh);
  57.         XFillRectangle(dpy, colwin, Data_GC[(i/k)], i, ADJHEIGHT-j, k, j);
  58.     }
  59. }
  60.  
  61. void 
  62. StartSegments(w, data, event)
  63. Window w;
  64. image_data_t *data;
  65. XButtonEvent *event;
  66. {
  67.     extern double A, B, C, D;
  68.     extern int histex;
  69.     static int hiscur=0;
  70.  
  71.     segments = 0;
  72.     switch (event->button) {
  73.         case Button1:
  74.             if ((histex != -2) || (event->x < ADJWIDTH/2)) {
  75.                 segments = 1;
  76.                 data->rubber_band.last_x = event->x;
  77.                 data->rubber_band.last_y = ADJHEIGHT - event->y;
  78.                 drawmap(A, B, C, D);    /* erase */
  79.                 if ((histex == 0) && (event->x > ((A+C)/2)*ADJWIDTH)) {
  80.                     segments = 2;
  81.                     drawmap(A,B,
  82.                         (double)data->rubber_band.last_x/(double)ADJWIDTH,
  83.                         (double)data->rubber_band.last_y/(double)ADJHEIGHT);
  84.                 }
  85.                 else
  86.                     drawmap((double)data->rubber_band.last_x/(double)ADJWIDTH,
  87.                         (double)data->rubber_band.last_y/(double)ADJHEIGHT,C,D);
  88.             }
  89.             break;
  90.         case Button2:
  91.             drawmap(A, B, C, D);
  92.             A = B = 0.5;
  93.             drawmap(A, B, C, D);
  94.             break;
  95.         case Button3:
  96.             hiscur = (!hiscur);
  97.             if (hiscur) {
  98.                 drawmap(A, B, C, D);
  99.                 drawhis();
  100.             }
  101.             else {
  102.                 XClearWindow(dpy, colwin);
  103.                 drawmap(A, B, C, D);
  104.             }
  105.             break;
  106.     }
  107. }
  108.  
  109. int
  110. checkwin(x, y)
  111. int x, y;
  112. {
  113.     if (((x>0) && (x<ADJWIDTH)) && ((y>0) && (y<ADJHEIGHT)))
  114.         return(1);
  115.     else
  116.         return(0);
  117. }
  118.  
  119. void 
  120. TrackSegments(w, data, event)
  121. Window w;
  122. image_data_t *data;
  123. XButtonEvent *event;
  124. {
  125.     extern int histex;
  126.     extern double A, B, C, D;
  127.  
  128.     if (segments) {
  129.         if (checkwin(data->rubber_band.last_x, data->rubber_band.last_y)) {
  130.             /* erase old lines */
  131.             if (segments == 2)
  132.                 drawmap(A,B,(double)data->rubber_band.last_x/(double)ADJWIDTH,
  133.                         (double)data->rubber_band.last_y/(double)ADJHEIGHT);
  134.             else
  135.                 drawmap((double)data->rubber_band.last_x/(double)ADJWIDTH,
  136.                         (double)data->rubber_band.last_y/(double)ADJHEIGHT,C,D);
  137.         }
  138.         if ((histex != -2) || (event->x < ADJWIDTH/2)) {
  139.             data->rubber_band.last_x = event->x;
  140.             data->rubber_band.last_y = ADJHEIGHT - event->y;
  141.             if (checkwin(data->rubber_band.last_x, data->rubber_band.last_y)) {
  142.               if (segments == 2)
  143.                 drawmap(A, B, (double)event->x/(double)ADJWIDTH,
  144.                         ((double)data->rubber_band.last_y/(double)ADJHEIGHT));
  145.               else
  146.                 drawmap((double)event->x/(double)ADJWIDTH,
  147.                         (double)data->rubber_band.last_y/(double)ADJHEIGHT,C,D);
  148.             }
  149.         }
  150.         else {
  151.             if (checkwin(data->rubber_band.last_x, data->rubber_band.last_y)) {
  152.                 drawmap((double)data->rubber_band.last_x/(double)ADJWIDTH,
  153.                         (double)data->rubber_band.last_y/(double)ADJHEIGHT,C,D);
  154.             }
  155.         }
  156.     }
  157. }
  158.  
  159. void 
  160. EndSegments(w, data, event)
  161. Window w;
  162. image_data_t *data;
  163. XButtonEvent *event;
  164. {
  165.     extern double A, B, C, D;
  166.     extern void Redraw_Hist();
  167.  
  168.     if (segments) {
  169.         if (checkwin(data->rubber_band.last_x, data->rubber_band.last_y)) {
  170.             if (segments == 2) {
  171.                 C = (double)data->rubber_band.last_x/(double)ADJWIDTH;
  172.                 D = (double)data->rubber_band.last_y/(double)ADJHEIGHT;
  173.             }
  174.             else {
  175.                 A = (double)data->rubber_band.last_x/(double)ADJWIDTH;
  176.                 B = (double)data->rubber_band.last_y/(double)ADJHEIGHT;
  177.             }
  178.             Redraw_Hist();
  179.         }
  180.         else
  181.             drawmap(A, B, C, D);
  182.         segments = 0;
  183.     }
  184. }
  185.  
  186. void 
  187. StartRubberBand(w, data, event)
  188. Window w;
  189. image_data_t *data;
  190. XButtonEvent *event;
  191. {
  192.     XPoint corners[5];
  193.     double x, y;
  194.     static int wid, hei;
  195.     extern void SetupCorners();
  196.  
  197.     nostart = 0;
  198.     rubberband = 0;
  199.     winrot = 0;
  200.     switch (event->button) {
  201.         case Button1:
  202.             if (clearflag) {
  203.                 clearflag=0;
  204.                 toggle=1;
  205.             }
  206.             rubberband=1;
  207.             data->rubber_band.last_x = data->rubber_band.start_x = event->x;
  208.             data->rubber_band.last_y = data->rubber_band.start_y = event->y;
  209.             SetupCorners(corners, data);
  210.             XDrawLines(dpy, w, RubberGC, corners, 
  211.                     sizeof(corners) / sizeof(corners[0]), CoordModeOrigin);
  212.             break;
  213. #ifdef USE_3D
  214.       case Button2:
  215.             winrot = 1;
  216.             if (w == trajec) {
  217.                 if (thermometer)
  218.                     wid = (trawidth-THERMWIDTH)/2;
  219.                 else
  220.                     wid = trawidth/2;
  221.                 hei = traheight/2;
  222.             }
  223.             else if (w == crijec) {
  224.                 if (thermometer)
  225.                     wid = (criwidth-THERMWIDTH)/2;
  226.                 else
  227.                     wid = criwidth/2;
  228.                 hei = criheight/2;
  229.             }
  230.             else if (w == prejec) {
  231.                 wid = width/2;
  232.                 hei = height/2;
  233.             }
  234.             else {
  235.                 wid = width/2;
  236.                 hei = height/2;
  237.             }
  238.             x = ((double)(event->x - wid) / (double)wid) * 180.0;
  239.             y = ((double)(event->y - hei) / (double)hei) * 180.0;
  240.             sprintf(xystr," (%lf,%lf) ",x,y);
  241.             x_str = (wid/2);
  242.             y_str = (2*hei) - 20;
  243.             XDrawImageString(dpy,w,Data_GC[1],x_str,y_str,xystr,strlen(xystr));
  244.             break;
  245.       case Button3:
  246.             winrot = 2;
  247.             x_str = event->x;
  248.             y_str = event->y;
  249.             break;
  250. #endif
  251.     }
  252. }
  253.  
  254. void
  255. SetupCorners(corners, data)
  256. XPoint *corners;
  257. image_data_t *data;
  258. {
  259.     corners[0].x = data->rubber_band.start_x;
  260.     corners[0].y = data->rubber_band.start_y;
  261.     corners[1].x = data->rubber_band.start_x;
  262.     corners[1].y = data->rubber_band.last_y;
  263.     corners[2].x = data->rubber_band.last_x;
  264.     corners[2].y = data->rubber_band.last_y;
  265.     corners[3].x = data->rubber_band.last_x;
  266.     corners[3].y = data->rubber_band.start_y;
  267.     corners[4] = corners[0];
  268. }
  269.  
  270. void 
  271. TrackRubberBand(w, data, event)
  272. Window w;
  273. image_data_t *data;
  274. XButtonEvent *event;
  275. {
  276.     XPoint corners[5];
  277.     int xdiff, ydiff;
  278.     double x, y, z;
  279.     static int wid, hei;
  280.     extern void SetupCorners(); 
  281.     extern int axes;
  282. #ifdef USE_3D
  283.     extern void TranslateWindow(), Draw_Axes();
  284.     extern triple window_center;
  285.     static triple tvec;
  286. #endif
  287.  
  288.     if (rubberband) {
  289.         if (nostart)
  290.             return;
  291.         SetupCorners(corners, data);
  292.         XDrawLines(dpy, w, RubberGC,
  293.             corners, sizeof(corners) / sizeof(corners[0]), CoordModeOrigin);
  294.         ydiff = event->y - data->rubber_band.start_y;
  295.         xdiff = event->x - data->rubber_band.start_x;
  296.         data->rubber_band.last_x = data->rubber_band.start_x + xdiff;
  297.         data->rubber_band.last_y = data->rubber_band.start_y + ydiff;
  298.         if (data->rubber_band.last_y < data->rubber_band.start_y ||
  299.             data->rubber_band.last_x < data->rubber_band.start_x) {
  300.             data->rubber_band.last_y = data->rubber_band.start_y;
  301.             data->rubber_band.last_x = data->rubber_band.start_x;
  302.         }
  303.         SetupCorners(corners, data);
  304.         XDrawLines(dpy, w, RubberGC,
  305.             corners, sizeof(corners) / sizeof(corners[0]), CoordModeOrigin);
  306.     }
  307. #ifdef USE_3D
  308.     else if (winrot) {
  309.         if (w == trajec) {
  310.             if (thermometer)
  311.                 wid = (trawidth-THERMWIDTH)/2;
  312.             else
  313.                 wid = trawidth/2;
  314.             hei = traheight/2;
  315.         }
  316.         else if (w == crijec) {
  317.             if (thermometer)
  318.                 wid = (criwidth-THERMWIDTH)/2;
  319.             else
  320.                 wid = criwidth/2;
  321.             hei = criheight/2;
  322.         }
  323.         else if (w == prejec) {
  324.             wid = width/2;
  325.             hei = height/2;
  326.         }
  327.         else {
  328.             wid = width/2;
  329.             hei = height/2;
  330.         }
  331.         if (winrot == 1) {
  332.             x = ((double)(event->x - wid) / (double)wid) * 180.0;
  333.             y = ((double)(event->y - hei) / (double)hei) * 180.0;
  334.             sprintf(xystr," (%lf,%lf) ",x,y);
  335.             x_str = (wid/2);
  336.             y_str = (2*hei) - 20;
  337.             XDrawImageString(dpy,w,Data_GC[1],x_str,y_str,xystr,strlen(xystr));
  338.         }
  339.         else {
  340.             if ((ABS(event->x - x_str)>(wid/20)) || 
  341.                 (ABS(event->y - y_str)>(hei/20))) {
  342.                 VECTORIZE(tvec, window_right, window_center);
  343.                 z = (double)(event->x - x_str) / (double)wid;
  344.                 VECTOR_X_SCALAR(tvec, tvec, z);
  345.                 if (axes)
  346.                     Draw_Axes(w, 0);
  347.                 TranslateWindow(tvec);
  348.                 VECTORIZE(tvec, window_top, window_center);
  349.                 z = (double)(event->y - y_str) / (double)hei;
  350.                 VECTOR_X_SCALAR(tvec, tvec, z);
  351.                 TranslateWindow(tvec);
  352.                 x_str = event->x; y_str = event->y;
  353.                 Clear(w);
  354.                 if (axes)
  355.                 Draw_Axes(w, 1);
  356.               }
  357.         }
  358.     }
  359.     else {
  360. #endif
  361.         x = (((double)event->x / (double)width) * x_range) + min_x;
  362.         y = (((double)(height-event->y) / (double)height) * y_range) + min_y;
  363.         sprintf(xystr," (%lf,%lf) ",x,y);
  364.         XDrawImageString(dpy,w,Data_GC[1],x_str,y_str,xystr,
  365.                     strlen(xystr));
  366. #ifdef USE_3D
  367.     }
  368. #endif
  369. }
  370.  
  371. void 
  372. EndRubberBand(w, data, event)
  373. Window w;
  374. image_data_t *data;
  375. XButtonEvent *event;
  376. {
  377.     XPoint corners[5];
  378.     XPoint top, bot;
  379.     double del, diff, xeven, yeven;
  380.     static int wid, hei;
  381.     extern int axes;
  382. #ifdef USE_3D
  383.     static triple rotate_axis;
  384.     extern void TranslateWindow(), Draw_Axes();
  385. #endif
  386.     extern void set_new_params(), SetupCorners(); 
  387.  
  388.     switch (event->button) {
  389.         case Button1:
  390.             nostart = 1;
  391.             rubberband = 1;
  392.             SetupCorners(corners, data);
  393.             XDrawLines(dpy, w, RubberGC,
  394.                 corners, sizeof(corners) / sizeof(corners[0]), CoordModeOrigin);
  395.             if (data->rubber_band.start_x >= data->rubber_band.last_x ||
  396.                 data->rubber_band.start_y >= data->rubber_band.last_y)
  397.                 return;
  398.             top.x = data->rubber_band.start_x;
  399.             bot.x = data->rubber_band.last_x;
  400.             top.y = data->rubber_band.start_y;
  401.             bot.y = data->rubber_band.last_y;
  402.             diff = data->q_max - data->q_min;
  403.             if (w == trajec) {
  404.                 if (thermometer)
  405.                     wid = trawidth-THERMWIDTH;
  406.                 else
  407.                     wid = trawidth;
  408.                 hei = traheight;
  409.         /* Gack! Why doesn't this work ?
  410.          *        if (orbits_3d) {
  411.          *            diff = (double)top.y / (double)hei;
  412.          *            VECTORIZE(rotate_axis,window_upper_right,window_right);
  413.          *            VECTOR_X_SCALAR(rotate_axis, rotate_axis, 2.0 * diff);
  414.          *            TranslateWindow(rotate_axis);
  415.          *            VECTOR_X_SCALAR(rotate_axis, rotate_axis, -1.0);
  416.          *            TranslateView(rotate_axis);
  417.          *            del = 1.0 - ((double)bot.x / (double)wid);
  418.          *            VECTORIZE(rotate_axis,window_upper_right,window_top);
  419.          *            VECTOR_X_SCALAR(rotate_axis, rotate_axis, 2.0 * del);
  420.          *            TranslateWindow(rotate_axis);
  421.          *            VECTOR_X_SCALAR(rotate_axis, rotate_axis, -1.0);
  422.          *            TranslateView(rotate_axis);
  423.          *            del = (double)(bot.x - top.x) / (double)wid;
  424.          *            diff = (double)(bot.y - top.y) / (double)hei;
  425.          *             ScaleWindow(del, diff);
  426.          *            Clear(trajec);
  427.          *            break;
  428.          *        }
  429.          */
  430.             }
  431.             else if (w == crijec) {
  432.                 if (thermometer)
  433.                     wid = criwidth-THERMWIDTH;
  434.                 else
  435.                     wid = criwidth;
  436.                 hei = criheight;
  437.             }
  438.             else if (w == prejec) {
  439.                 wid = width;
  440.                 hei = height;
  441.             }
  442.             else {
  443.                 wid = width;
  444.                 hei = height;
  445.             }
  446.             del = (double)(hei-bot.y) / (double)hei;
  447.             data->q_min += diff * del;
  448.             del = (double)top.y / (double)hei;
  449.             data->q_max -= diff * del;
  450.             diff = data->p_max - data->p_min;
  451.             del = (double)top.x / (double)wid;
  452.             data->p_min += diff * del;
  453.             del = (double)(wid - bot.x) / (double)wid;
  454.             data->p_max -= diff * del;
  455.             fflush(stdout);
  456.             set_new_params(w, data);
  457.             if (toggle) {
  458.                 toggle=0;
  459.                 clearflag=1;
  460.             }
  461.             break;
  462. #ifdef USE_3D
  463.         case Button2:
  464.             if (w == trajec) {
  465.                 if (thermometer)
  466.                     wid = (trawidth-THERMWIDTH)/2;
  467.                 else
  468.                     wid = trawidth/2;
  469.                 hei = traheight/2;
  470.             }
  471.             else if (w == crijec) {
  472.                 if (thermometer)
  473.                     wid = (criwidth-THERMWIDTH)/2;
  474.                 else
  475.                     wid = criwidth/2;
  476.                 hei = criheight/2;
  477.             }
  478.             else if (w == prejec) {
  479.                 wid = width/2;
  480.                 hei = height/2;
  481.             }
  482.             else {
  483.                 wid = width/2;
  484.                 hei = height/2;
  485.             }
  486.             xeven = ((double)(event->x - wid) / (double)wid) * 180.0;
  487.             yeven = ((double)((hei-event->y) - hei) / (double)hei) * 180.0;
  488.             VECTORIZE(rotate_axis, window_center, window_right);
  489.             UNIT_VECTOR(rotate_axis, rotate_axis, VECTOR_LENGTH(rotate_axis));
  490.             if (axes)
  491.                 Draw_Axes(w, 0);
  492.             RotateWindow( & yeven, & rotate_axis );
  493.             VECTORIZE(rotate_axis, window_center, window_top);
  494.             UNIT_VECTOR(rotate_axis, rotate_axis, VECTOR_LENGTH(rotate_axis));
  495.             RotateWindow( & xeven, & rotate_axis );
  496.             Clear(w);
  497.             if (axes)
  498.                 Draw_Axes(w, 1);
  499.             break;
  500. #endif
  501.     }
  502. }
  503.  
  504. void
  505. set_new_params(w, data)
  506. Window w;
  507. image_data_t *data;
  508. {
  509.     static XWindowAttributes attr;
  510.     extern int Qflag, p_inc, q_inc;
  511.  
  512.     if (w == crijec) {
  513.         c_x_range = data->p_max - data->p_min;
  514.         c_y_range = data->q_max - data->q_min;
  515.         c_min_x = data->p_min;
  516.         c_min_y = data->q_min;
  517.         Clear(crijec);
  518.         if (critical) Remap_crit(crijec);
  519.     }
  520.     else if (w == trajec) {
  521.         t_x_range = data->p_max - data->p_min;
  522.         t_y_range = data->q_max - data->q_min;
  523.         t_min_x = data->p_min;
  524.         t_min_y = data->q_min;
  525.         Clear(trajec);
  526.     }
  527.     else {
  528.         frame = (maxframe + 1) % MAXFRAMES;
  529.         if (frame > maxframe)
  530.             maxframe = frame;
  531.         x_range = data->p_max - data->p_min;
  532.         y_range = data->q_max - data->q_min;
  533.         a_minimums[frame] = min_x = data->p_min;
  534.         b_minimums[frame] = min_y = data->q_min;
  535.         x_inc = x_range / (double)width;
  536.         y_inc = y_range / (double)height;
  537.         a_maximums[frame] = max_x = data->p_max;
  538.         b_maximums[frame] = max_y = data->q_max;
  539.         point.x = 0;
  540.         point.y = 0;
  541.         maxexp = minexp = 0;
  542.         run = 1;
  543.         x = min_x;
  544.         y = min_y;
  545.         row = 1; numrows = 1;
  546.         if (Qflag == 4) {
  547.             x_inc = x_range / 4.0;
  548.             y_inc = y_range / 4.0;
  549.             p_inc = width / 4;
  550.             q_inc = height / 4;
  551.             numrows = row = 4;
  552.         }
  553.         perind[frame] = 0;;
  554.         Clear(which); Clear(prejec);
  555.     }
  556.     XGetWindowAttributes(dpy, info, &attr);
  557.     if (attr.map_state != IsUnmapped)
  558.         Show_Info();
  559. }
  560.